Imports System.Drawing.Drawing2D

Namespace Controls.TabControl

    Public Class ExtendedTabControl
        Inherits System.Windows.Forms.TabControl

        Public Event TabClosed(ByVal sender As ExtendedTabControl, ByVal e As CloseEventArgs)
        Private components As System.ComponentModel.Container = Nothing

        Public Sub New()

            InitializeComponent()

        End Sub

        Private _confirmOnClose As Boolean = True
        Public Property ConfirmOnClose() As Boolean
            Get
                Return _confirmOnClose
            End Get
            Set(ByVal value As Boolean)
                _confirmOnClose = value
            End Set
        End Property

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)

            If disposing Then
                If components IsNot Nothing Then
                    components.Dispose()
                End If
            End If

            MyBase.Dispose(disposing)

        End Sub

#Region "Component Designer Generated Code"

        Private Sub InitializeComponent()

            components = New System.ComponentModel.Container()
            SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
            Me.TabStop = False
            Me.DrawMode = TabDrawMode.OwnerDrawFixed
            Me.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (CByte(0)))
            Me.ItemSize = New System.Drawing.Size(230, 24)

        End Sub


#End Region

        Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)

            If e.Bounds <> RectangleF.Empty Then

                e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                Dim tabTextArea As RectangleF = RectangleF.Empty

                For i As Integer = 0 To Me.TabCount - 1

                    If i <> Me.SelectedIndex Then

                        tabTextArea = Me.GetTabRect(i)
                        Dim path As New GraphicsPath()
                        path.AddRectangle(tabTextArea)

                        Using brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)

                            Dim colorBlend As New ColorBlend(3)
                            colorBlend.Colors = New Color() {SystemColors.ControlLight, _
                                                                Color.FromArgb(255, SystemColors.ControlLight), _
                                                                SystemColors.ControlDark, _
                                                                SystemColors.ControlLightLight}

                            colorBlend.Positions = New Single() {0.0F, 0.4F, 0.5F, 1.0F}
                            brush.InterpolationColors = colorBlend

                            e.Graphics.FillPath(brush, path)
                            Using pen As New Pen(SystemColors.ActiveBorder)

                                e.Graphics.DrawPath(pen, path)

                            End Using

                            colorBlend.Colors = New Color() {SystemColors.ActiveBorder, _
                                                             SystemColors.ActiveBorder, _
                                                             SystemColors.ActiveBorder, _
                                                             SystemColors.ActiveBorder}


                            colorBlend.Positions = New Single() {0.0F, 0.4F, 0.5F, 1.0F}
                            brush.InterpolationColors = colorBlend

                            e.Graphics.FillRectangle(brush, tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 3, tabTextArea.Height - 5)
                            e.Graphics.DrawRectangle(Pens.White, tabTextArea.X + tabTextArea.Width - 20, 6, tabTextArea.Height - 8, tabTextArea.Height - 9)

                            Using pen As New Pen(Color.White, 2)

                                e.Graphics.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 9, tabTextArea.X + tabTextArea.Width - 7, 17)
                                e.Graphics.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 17, tabTextArea.X + tabTextArea.Width - 7, 9)

                            End Using

                        End Using

                        path.Dispose()

                    Else

                        tabTextArea = Me.GetTabRect(i)
                        Dim path As New GraphicsPath()
                        path.AddRectangle(tabTextArea)

                        Using brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)

                            Dim colorBlend As New ColorBlend(3)
                            colorBlend.Colors = New Color() {SystemColors.ControlLightLight, _
                                                                Color.FromArgb(255, SystemColors.Control), _
                                                                SystemColors.ControlLight, _
                                                                SystemColors.Control}

                            colorBlend.Positions = New Single() {0.0F, 0.4F, 0.5F, 1.0F}
                            brush.InterpolationColors = colorBlend

                            e.Graphics.FillPath(brush, path)
                            Using pen As New Pen(SystemColors.ActiveBorder)

                                e.Graphics.DrawPath(pen, path)

                            End Using

                            'Drawing Close Button
                            colorBlend.Colors = New Color() {Color.FromArgb(255, 231, 164, 152), _
                                                        Color.FromArgb(255, 231, 164, 152), _
                                                        Color.FromArgb(255, 197, 98, 79), _
                                                        Color.FromArgb(255, 197, 98, 79)}

                            brush.InterpolationColors = colorBlend
                            e.Graphics.FillRectangle(brush, tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 3, tabTextArea.Height - 5)
                            e.Graphics.DrawRectangle(Pens.White, tabTextArea.X + tabTextArea.Width - 20, 6, tabTextArea.Height - 8, tabTextArea.Height - 9)
                            Using pen As New Pen(Color.White, 2)

                                e.Graphics.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 9, tabTextArea.X + tabTextArea.Width - 7, 17)
                                e.Graphics.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 17, tabTextArea.X + tabTextArea.Width - 7, 9)

                            End Using

                        End Using

                        path.Dispose()

                    End If

                    Dim str As String = Me.TabPages(i).Text
                    Dim stringFormat As New StringFormat()
                    stringFormat.Alignment = StringAlignment.Near
                    e.Graphics.DrawString(str, Me.Font, New SolidBrush(Me.TabPages(i).ForeColor), tabTextArea, stringFormat)

                Next

            End If

        End Sub

        Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)


            Dim g As Graphics = CreateGraphics()
            g.SmoothingMode = SmoothingMode.AntiAlias
            Dim tabTextArea As RectangleF = RectangleF.Empty

            For i As Integer = 0 To Me.TabCount - 1
                If i <> Me.SelectedIndex Then
                    tabTextArea = Me.GetTabRect(i)
                    Dim _Path As New GraphicsPath()
                    _Path.AddRectangle(tabTextArea)
                    Using _Brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)
                        Dim _ColorBlend As New ColorBlend(3)

                        _ColorBlend.Colors = New Color() {SystemColors.ActiveBorder, SystemColors.ActiveBorder, SystemColors.ActiveBorder, SystemColors.ActiveBorder}

                        _ColorBlend.Positions = New Single() {0.0F, 0.4, 0.5F, 1.0F}
                        _Brush.InterpolationColors = _ColorBlend
                        g.FillRectangle(_Brush, tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 2, tabTextArea.Height - 5)
                        g.DrawRectangle(Pens.White, tabTextArea.X + tabTextArea.Width - 20, 6, tabTextArea.Height - 8, tabTextArea.Height - 9)
                        Using pen As New Pen(Color.White, 2)
                            g.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 9, tabTextArea.X + tabTextArea.Width - 7, 17)
                            g.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 17, tabTextArea.X + tabTextArea.Width - 7, 9)
                        End Using

                    End Using

                    _Path.Dispose()
                Else

                    tabTextArea = Me.GetTabRect(i)
                    Dim _Path As New GraphicsPath()
                    _Path.AddRectangle(tabTextArea)
                    Using _Brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)
                        Dim _ColorBlend As New ColorBlend(3)
                        _ColorBlend.Positions = New Single() {0.0F, 0.4, 0.5F, 1.0F}

                        _ColorBlend.Colors = New Color() {Color.FromArgb(255, 231, 164, 152), Color.FromArgb(255, 231, 164, 152), Color.FromArgb(255, 197, 98, 79), Color.FromArgb(255, 197, 98, 79)}
                        _Brush.InterpolationColors = _ColorBlend
                        g.FillRectangle(_Brush, tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 3, tabTextArea.Height - 5)
                        g.DrawRectangle(Pens.White, tabTextArea.X + tabTextArea.Width - 20, 6, tabTextArea.Height - 8, tabTextArea.Height - 9)
                        Using pen As New Pen(Color.White, 2)
                            g.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 9, tabTextArea.X + tabTextArea.Width - 7, 17)
                            g.DrawLine(pen, tabTextArea.X + tabTextArea.Width - 16, 17, tabTextArea.X + tabTextArea.Width - 7, 9)
                        End Using

                    End Using
                    _Path.Dispose()

                End If
            Next
            g.Dispose()


        End Sub

        Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)

            If Not DesignMode Then
                Dim g As Graphics = CreateGraphics()
                g.SmoothingMode = SmoothingMode.AntiAlias
                For i As Integer = 0 To Me.TabCount - 1
                    Dim tabTextArea As RectangleF = Me.GetTabRect(i)
                    tabTextArea = New RectangleF(tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 3, tabTextArea.Height - 5)

                    Dim pt As New Point(e.X, e.Y)
                    If tabTextArea.Contains(pt) Then
                        Using _Brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)
                            Dim _ColorBlend As New ColorBlend(3)
                            _ColorBlend.Colors = New Color() {Color.FromArgb(255, 252, 193, 183), Color.FromArgb(255, 252, 193, 183), Color.FromArgb(255, 210, 35, 2), Color.FromArgb(255, 210, 35, 2)}
                            _ColorBlend.Positions = New Single() {0.0F, 0.4, 0.5F, 1.0F}
                            _Brush.InterpolationColors = _ColorBlend

                            g.FillRectangle(_Brush, tabTextArea)
                            g.DrawRectangle(Pens.White, tabTextArea.X + 2, 6, tabTextArea.Height - 3, tabTextArea.Height - 4)
                            Using pen As New Pen(Color.White, 2)
                                g.DrawLine(pen, tabTextArea.X + 6, 9, tabTextArea.X + 15, 17)
                                g.DrawLine(pen, tabTextArea.X + 6, 17, tabTextArea.X + 15, 9)
                            End Using
                        End Using
                    Else
                        If i <> SelectedIndex Then
                            Using _Brush As New LinearGradientBrush(tabTextArea, SystemColors.Control, SystemColors.ControlLight, LinearGradientMode.Vertical)
                                Dim _ColorBlend As New ColorBlend(3)
                                _ColorBlend.Colors = New Color() {SystemColors.ActiveBorder, SystemColors.ActiveBorder, SystemColors.ActiveBorder, SystemColors.ActiveBorder}
                                _ColorBlend.Positions = New Single() {0.0F, 0.4, 0.5F, 1.0F}
                                _Brush.InterpolationColors = _ColorBlend

                                g.FillRectangle(_Brush, tabTextArea)
                                g.DrawRectangle(Pens.White, tabTextArea.X + 2, 6, tabTextArea.Height - 3, tabTextArea.Height - 4)
                                Using pen As New Pen(Color.White, 2)
                                    g.DrawLine(pen, tabTextArea.X + 6, 9, tabTextArea.X + 15, 17)
                                    g.DrawLine(pen, tabTextArea.X + 6, 17, tabTextArea.X + 15, 9)
                                End Using
                            End Using
                        End If
                    End If

                Next
                g.Dispose()
            End If


        End Sub

        Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)

            Dim tabTextArea As RectangleF = Me.GetTabRect(SelectedIndex)

            tabTextArea = New RectangleF(tabTextArea.X + tabTextArea.Width - 22, 4, tabTextArea.Height - 3, tabTextArea.Height - 5)

            Dim pt As New Point(e.X, e.Y)
            If tabTextArea.Contains(pt) Then
                If ConfirmOnClose Then
                    If MessageBox.Show("You are about to close " & Me.TabPages(SelectedIndex).Text.TrimEnd() & " tab. Are you sure you want to continue?", "Confirm close", MessageBoxButtons.YesNo) = DialogResult.No Then
                        Return
                    End If
                End If
                'Fire Event to Client
                RaiseEvent TabClosed(Me, New CloseEventArgs(SelectedIndex))
            End If

        End Sub



    End Class

    Public Class CloseEventArgs
        Inherits EventArgs

        Public Sub New(ByVal tabIndex As Integer)
            Me.TabIndex = tabIndex
        End Sub

        Private _tabIndex As Integer
        Public Property TabIndex() As Integer
            Get
                Return _tabIndex
            End Get
            Set(ByVal value As Integer)
                _tabIndex = value
            End Set
        End Property

    End Class

End Namespace